// resolve 用来拼劲绝对路径的方法
const { resolve } = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerWebpackPlugin = require('css-minimizer-webpack-plugin');
const ESLintPlugin = require('eslint-webpack-plugin');
const TerserPlugin = require("terser-webpack-plugin");
const HtmlMinimizerPlugin = require("html-minimizer-webpack-plugin");
const webpack = require('webpack');

// 设置 nodejs 环境变量
//process.env.NODE_ENV = 'development';

const cssLoader = [
	// 取代 style-loader, 将 js 中的 css 单独提取成文件
	{
		loader: MiniCssExtractPlugin.loader,
		options: {
			publicPath: '../'
		}
	},
	// 将 css 文件变成 commonjs 模块加载到 js 中
	'css-loader',
	// css 兼容性处理
	'postcss-loader',
];

module.exports = {
	entry: ['./src/js/index.js'],
	output: {
		// 输出文件名, 可以不配置, 默认是 main.js
		filename: 'js/[name].js',
		// __dirname nodejs的变量, 表示当前文件的目录绝对路径
		path: resolve(__dirname, 'build'),
		clean: true,
		chunkFilename: 'js/chunk_[name].js', // 非入口 chunk 的名称
		// library: '[name]', // 整个库向外暴露的变量名
		// libraryTarget: 'window', // 变量名暴露到浏览器的 window 上
	},
	// loader 的配置
	module: {
		rules: [
			{
				oneOf: [
					{
						test: /\.m?js$/,
						exclude: /(node_modules|bower_components)/,
						use: [
							//"thread-loader",
							{
								loader: 'babel-loader',
								options: {
									cacheDirectory: true,
									presets: [
										[
											"@babel/preset-env",
											{
												useBuiltIns: "usage",
												corejs: '3.10', // 老版本只要指定大版本 3 就可以了, 新版本要求指定到具体版本
												// 可以针对不同浏览器更精确的配置, 一般不用配置
												// targets: {
												// ie: 9,
												// }
											}
										]
									],
									plugins: [
										[
											"@babel/plugin-transform-runtime"
										]
									]
								}
							}
						]
					},
					{
						// 匹配 css 结尾的文件
						test: /\.css$/,
						// use 数组中的执行顺序, 是从下到上 依次执行
						use: [
							...cssLoader
						],
					},
					{
						test: /\.less$/,
						use: [
							...cssLoader,
							// 需要 npm i less less-loader -D 包
							'less-loader',
						],
					},
					{
						test: /\.(jpg|png|gif)$/,
						// 使用一个 loader 时就可以用 loader, 而不是 use
						loader: 'url-loader',
						options: {
							// 图片小于 8 kb, 就会用 base64 处理
							// 优点: 减少请求数量 (减轻服务器压力)
							// 缺点: 图片体积变大
							limit: 8 * 1024,
							esModule: false,
							name: '[hash:10].[ext]',
							outputPath: 'imgs',
						},
					},
					{
						test: /\.html$/,
						// 使用一个 loader 时就可以用 loader, 而不是 use
						// html-loader 将 html 文件中的 img 转换为编译后的图片引入
						loader: 'html-loader',
						options: {
							esModule: false,
						},
					},
					{
						exclude: /\.(css|jpg|png|gif|js|html|less)$/,
						// 使用一个 loader 时就可以用 loader, 而不是 use
						// html-loader 将 html 文件中的 img 转换为编译后的图片引入
						loader: 'file-loader',
						options: {
							name: '[hash:10].[ext]',
							outputPath: 'media',
						},
					},
				]
			}
		],
	},
	plugins: [
		// 默认会创建一个空的 html, 并自动引入 js/css
		new HtmlWebpackPlugin({
			// 将指定的文件替代空 html, 自动引入 js/css
			template: './src/index.html',
			title: 'Caching',
		}),
		new MiniCssExtractPlugin({
			// 指定编译文件, 默认 main.css
			filename: 'css/[name].[contenthash:10].css',
		}),
		// new ESLintPlugin({
		// 	fix: true,
		// 	exclude: 'node_modules',
		// }),
	],
	// 对 css 进行压缩
	optimization: {
		minimize: true,
		splitChunks: {
			chunks: 'all'
		},
		minimizer: [new CssMinimizerWebpackPlugin(), new TerserPlugin(), new HtmlMinimizerPlugin()],
		usedExports: true,
	},
	// mode: 'development',
	mode: 'production',
	// 开发服务器: 自动编译, 自动打开浏览器, 自动刷新
	// 特点: 只会在内存中打包, 不会有任何输出
	// 启动指令: webpack-dev-server
	devServer: {
		contentBase: resolve(__dirname, 'build'),
		compress: true, // 启动 gzip 压缩
		port: 9999,
		open: true, // 自动打开浏览器
		hot: true,
		disableHostCheck: true,
	},
	target: process.env.NODE_ENV === 'development' ? 'web' : 'browserslist',
	devtool: 'inline-source-map',
	// externals: {
	// 	jquery: 'jQuery',
	// }
	resolve: {
		alias: {
			$imgs: resolve(__dirname, 'src/imgs')
		}
	}
};
